package synchronized_;

/**
 * @author DCSGO
 * @version 1.0
 * 线程的死锁 释放锁
 * 多个线程都占用了对方的锁资源，但不肯相让
 * 导致了死锁，在编程中一定要避免死锁的发生
 */
public class DeadLock {
    public static void main(String[] args) {
        T1 A = new T1(true);
        T1 B = new T1(false);
        A.setName("A线程 ");
        B.setName("B线程 ");
        A.start();
        B.start();
        //B线程 进入3
        //A线程 进入1
        //程序就卡在这儿了...
    }
}

class T1 extends Thread {
    public boolean loop;
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();

    public T1(boolean loop) {
        this.loop = loop;
    }

    @Override
    public void run() {
        if (loop) {
            synchronized (lock1) {//得到锁对象 lock1 方可执行
                System.out.println(currentThread().getName() + "进入1");
                synchronized (lock2) {//得到锁对象 lock2 方可执行
                    //这条语句只有当前线程即获得 lock1 又获得 lock2 才会执行
                    System.out.println(currentThread().getName() + "进入2");
                }
            }
        } else {
            synchronized (lock2) {
                System.out.println(currentThread().getName() + "进入3");
                synchronized (lock1) {
                    System.out.println(currentThread().getName() + "进入4");
                }
            }
        }
    }
}
/*
下面操作会释放锁
1.当前线程的同步方法、同步代码块执行结束
2.当前线程在同步代码块、同步方法中遇到 break、return 使执行结束
3.当前线程在同步代码块、同步方法中出现了未处理的Error或Exception，导致异常结束
4.当前线程在同步代码块、同步方法中执行了线程对象的wait()方法，当前线程暂停，并释放锁

下面操作不会释放锁
1．线程执行同步代码块或同步方法时，程序调用Thread.sleep()、Thread.yield()方
   法暂停当前线程的执行,不会释放锁
2．线程执行同步代码块时，其他线程调用了该线程的suspend()方法将该线程挂起，
   该线程不会释放锁。
提示: 应尽量避免使用suspend()和resume()来控制线程，方法不再推荐使用
 */
